/*************************************************************************
    > File Name: 5.producer_cond.c
    > Author: Ykk
    > Mail: 3393579535@qq.com 
    > Created Time: 2023年05月12日 星期五 21时12分56秒
 ************************************************************************/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<unistd.h>
#include<pthread.h>

typedef	struct _node_t{
	int  date;
	struct _node_t *next;
}node_t;

node_t *head = NULL;

pthread_mutex_t mutex;
pthread_cond_t cond;

//生产者线程
void *producer(void *arg)
{
	//循环生产产品
	while(1){
		//加锁
		pthread_mutex_lock(&mutex);

		//分配节点空间
		node_t *new = malloc(sizeof(node_t));
		if(NULL == new)
		{
			printf("malloc failed...\n");
			break;
		}	
		memset(new,0,sizeof(node_t));

		new->date = random()%100+1;
		new->next = NULL;

		new->next = head;
		head = new;
		printf("生产者生产%d\n",new->date);

		//解锁
		pthread_mutex_unlock(&mutex);

		//唤醒因条件变量而阻塞的线程
		pthread_cond_signal(&cond);

		sleep(1);
	}
	pthread_exit(NULL);
}
//消费者线程
void *customer(void *arg)
{
	node_t *tmp = NULL;
	//循环消费
	while(1)
	{
		//加锁
		pthread_mutex_lock(&mutex);

		if(NULL == head)
		{
			pthread_cond_wait(&cond,&mutex);
		}

		//头删
		tmp = head;
		head = head->next;
		printf("消费者消费%d\n",tmp->date);
		free(tmp);

		//解锁
		pthread_mutex_unlock(&mutex);
	}
	pthread_exit(NULL);
}
//生产者消费者模型 条件变量的模型
int main()
{
	pthread_t tid1 = -1, tid2 = -1;
	int ret = -1;

	srandom(getpid());

	ret = pthread_mutex_init(&mutex,NULL);
	if(0 != ret)
	{
		printf("pthread_mutex_init failed...\n");
		return 1;
	}
	ret = pthread_cond_init(&cond,NULL);
	if(0 != ret)
	{
		printf("pthread_cond_init failed...\n");
		return 1;
	}
	//创建两个线程 生产者线程 消费者线程
	pthread_create(&tid1,NULL,producer,NULL);
	pthread_create(&tid2,NULL,customer,NULL);

	//回收线程资源
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);

	return 0;
}
